home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / SerialIO.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  15KB  |  885 lines

  1. /*
  2. **    SerialIO.c
  3. **
  4. **    Serial read/write routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. STATIC BOOL         ReadQueued        = FALSE,
  17.                  WriteQueued    = FALSE;
  18.  
  19. STATIC UBYTE    *QueueReadBuffer;
  20. STATIC LONG         QueueReadSize;
  21.  
  22.     /* ResetSerialRead():
  23.      *
  24.      *    Reset the read status.
  25.      */
  26.  
  27. VOID
  28. ResetSerialRead()
  29. {
  30.     ReadQueued        = FALSE;
  31.     QueueReadBuffer    = NULL;
  32.     QueueReadSize    = 0;
  33. }
  34.  
  35.     /* CheckSerialRead():
  36.      *
  37.      *    Check if a read request is finished.
  38.      */
  39.  
  40. BOOL
  41. CheckSerialRead()
  42. {
  43.     if(ReadRequest && ReadQueued)
  44.     {
  45.         if(CheckIO((struct IORequest *)ReadRequest))
  46.             return(TRUE);
  47.     }
  48.  
  49.     return(FALSE);
  50. }
  51.  
  52.     /* WaitSerialRead():
  53.      *
  54.      *    Wait for the read request to terminate.
  55.      */
  56.  
  57. BYTE
  58. WaitSerialRead()
  59. {
  60.     if(ReadRequest && ReadQueued)
  61.     {
  62.         ReadQueued        = FALSE;
  63.         QueueReadBuffer    = NULL;
  64.         QueueReadSize    = 0;
  65.  
  66.         return(WaitIO((struct IORequest *)ReadRequest));
  67.     }
  68.     else
  69.         return(0);
  70. }
  71.  
  72.     /* FlushSerialRead():
  73.      *
  74.      *    Forget about the current contents of the serial
  75.      *    read buffer.
  76.      */
  77.  
  78. BYTE
  79. FlushSerialRead()
  80. {
  81.     if(ReadRequest)
  82.     {
  83.         UBYTE *WasQueueReadBuffer;
  84.         LONG WasQueueReadSize;
  85.         BOOL WasReading;
  86.  
  87.         WasReading            = ReadQueued;
  88.         WasQueueReadBuffer    = QueueReadBuffer;
  89.         WasQueueReadSize    = QueueReadSize;
  90.  
  91.         StopSerialRead();
  92.  
  93.         DoSerialCmd(CMD_CLEAR);
  94.  
  95.         if(WasReading)
  96.             StartSerialRead(WasQueueReadBuffer,WasQueueReadSize);
  97.     }
  98.  
  99.     return(0);
  100. }
  101.  
  102.     /* DoSerialBreak():
  103.      *
  104.      *    Send a break signal.
  105.      */
  106.  
  107. BYTE
  108. DoSerialBreak()
  109. {
  110.     if(WriteRequest)
  111.     {
  112.         UBYTE *WasQueueReadBuffer;
  113.         LONG WasQueueReadSize;
  114.         BOOL WasReading;
  115.  
  116.         WasReading            = ReadQueued;
  117.         WasQueueReadBuffer    = QueueReadBuffer;
  118.         WasQueueReadSize    = QueueReadSize;
  119.  
  120.         StopSerialRead();
  121.  
  122.         DoSerialCmd(SDCMD_BREAK);
  123.  
  124.         if(WasReading)
  125.             StartSerialRead(WasQueueReadBuffer,WasQueueReadSize);
  126.     }
  127.  
  128.     return(0);
  129. }
  130.  
  131.     /* CompletelyFlushSerialRead():
  132.      *
  133.      *    Flush the serial read buffer over and over again until
  134.      *    no more data comes in.
  135.      */
  136.  
  137. VOID
  138. CompletelyFlushSerialRead()
  139. {
  140.     if(ReadRequest && WriteRequest)
  141.     {
  142.         UBYTE *WasQueueReadBuffer;
  143.         LONG WasQueueReadSize;
  144.         BOOL WasReading;
  145.  
  146.         WasReading            = ReadQueued;
  147.         WasQueueReadBuffer    = QueueReadBuffer;
  148.         WasQueueReadSize    = QueueReadSize;
  149.  
  150.         StopSerialRead();
  151.  
  152.         do
  153.         {
  154.             DoSerialCmd(CMD_CLEAR);
  155.  
  156.             DelayTime(1,0);
  157.         }
  158.         while(GetSerialWaiting());
  159.  
  160.         if(WasReading)
  161.             StartSerialRead(WasQueueReadBuffer,WasQueueReadSize);
  162.     }
  163. }
  164.  
  165.     /* StopSerialRead():
  166.      *
  167.      *    Force a read request to terminate.
  168.      */
  169.  
  170. VOID
  171. StopSerialRead()
  172. {
  173.     if(ReadRequest && ReadQueued)
  174.     {
  175.         if(!CheckIO((struct IORequest *)ReadRequest))
  176.             AbortIO((struct IORequest *)ReadRequest);
  177.  
  178.         WaitIO((struct IORequest *)ReadRequest);
  179.  
  180.         ReadQueued        = FALSE;
  181.         QueueReadBuffer    = NULL;
  182.         QueueReadSize    = 0;
  183.     }
  184. }
  185.  
  186.     /* StartSerialRead(ULONG Length,APTR Data):
  187.      *
  188.      *    Start a serial read request asynchronously.
  189.      */
  190.  
  191. VOID
  192. StartSerialRead(APTR Data,ULONG Length)
  193. {
  194.     if(ReadRequest)
  195.     {
  196.         if(ReadQueued)
  197.             StopSerialRead();
  198.  
  199.         ReadRequest->IOSer.io_Command    = CMD_READ;
  200.         ReadRequest->IOSer.io_Length    = Length;
  201.         ReadRequest->IOSer.io_Data        = Data;
  202.  
  203.         ClrSignal(1L << ReadPort->mp_SigBit);
  204.  
  205.         SendIO((struct IORequest *)ReadRequest);
  206.  
  207.         ReadQueued        = TRUE;
  208.         QueueReadBuffer    = Data;
  209.         QueueReadSize    = Length;
  210.     }
  211. }
  212.  
  213.     /* DoSerialRead(ULONG Length,APTR Data):
  214.      *
  215.      *    Perform a read request synchronously.
  216.      */
  217.  
  218. BYTE
  219. DoSerialRead(APTR Data,ULONG Length)
  220. {
  221.     if(ReadRequest)
  222.     {
  223.         if(ReadQueued)
  224.             StopSerialRead();
  225.  
  226.         ReadRequest->IOSer.io_Command    = CMD_READ;
  227.         ReadRequest->IOSer.io_Length    = Length;
  228.         ReadRequest->IOSer.io_Data        = Data;
  229.  
  230.         return(DoIO((struct IORequest *)ReadRequest));
  231.     }
  232.     else
  233.         return(IOERR_SELFTEST);
  234. }
  235.  
  236.     /* ResetSerialWrite():
  237.      *
  238.      *    Reset the write status.
  239.      */
  240.  
  241. VOID
  242. ResetSerialWrite()
  243. {
  244.     WriteQueued = FALSE;
  245. }
  246.  
  247.     /* WaitSerialWrite():
  248.      *
  249.      *    Wait for the write request to terminate.
  250.      */
  251.  
  252. BYTE
  253. WaitSerialWrite()
  254. {
  255.     if(WriteRequest && WriteQueued)
  256.     {
  257.         WriteQueued = FALSE;
  258.  
  259.         return(WaitIO((struct IORequest *)WriteRequest));
  260.     }
  261.     else
  262.         return(0);
  263. }
  264.  
  265.     /* StopSerialWrite():
  266.      *
  267.      *    Force a write request to terminate.
  268.      */
  269.  
  270. VOID
  271. StopSerialWrite()
  272. {
  273.     if(WriteRequest && WriteQueued)
  274.     {
  275.         if(!CheckIO((struct IORequest *)WriteRequest))
  276.             AbortIO((struct IORequest *)WriteRequest);
  277.  
  278.         WaitIO((struct IORequest *)WriteRequest);
  279.  
  280.         WriteQueued = FALSE;
  281.     }
  282. }
  283.  
  284.     /* StartSerialWrite(ULONG Length,APTR Data):
  285.      *
  286.      *    Start a serial write request asynchronously.
  287.      */
  288.  
  289. VOID
  290. StartSerialWrite(APTR Data,ULONG Length)
  291. {
  292.     if(WriteRequest)
  293.     {
  294.         if(WriteQueued)
  295.             StopSerialWrite();
  296.  
  297.         WriteRequest->IOSer.io_Command    = CMD_WRITE;
  298.         WriteRequest->IOSer.io_Length    = Length;
  299.         WriteRequest->IOSer.io_Data        = Data;
  300.  
  301.         ClrSignal(1L << WriteRequest->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
  302.  
  303.         SendIO((struct IORequest *)WriteRequest);
  304.  
  305.         WriteQueued = TRUE;
  306.     }
  307. }
  308.  
  309.     /* DoSerialWrite(ULONG Length,APTR Data):
  310.      *
  311.      *    Perform a write request synchronously.
  312.      */
  313.  
  314. BYTE
  315. DoSerialWrite(APTR Data,ULONG Length)
  316. {
  317.     if(WriteRequest)
  318.     {
  319.         if(WriteQueued)
  320.             StopSerialWrite();
  321.  
  322.         WriteRequest->IOSer.io_Command    = CMD_WRITE;
  323.         WriteRequest->IOSer.io_Length    = Length;
  324.         WriteRequest->IOSer.io_Data        = Data;
  325.  
  326.         return(DoIO((struct IORequest *)WriteRequest));
  327.     }
  328.     else
  329.         return(IOERR_SELFTEST);
  330. }
  331.  
  332.     /* DoSerialCmd(UWORD Command):
  333.      *
  334.      *    Perform single command.
  335.      */
  336.  
  337. BYTE
  338. DoSerialCmd(LONG Command)
  339. {
  340.     if(WriteRequest)
  341.     {
  342.         if(WriteQueued)
  343.             StopSerialWrite();
  344.  
  345.         WriteRequest->IOSer.io_Command = Command;
  346.  
  347.         return(DoIO((struct IORequest *)WriteRequest));
  348.     }
  349.     else
  350.         return(IOERR_SELFTEST);
  351. }
  352.  
  353.     /* GetSerialWaiting():
  354.      *
  355.      *    Query the number of bytes still waiting to be read
  356.      *    from the serial port.
  357.      */
  358.  
  359. ULONG
  360. GetSerialWaiting()
  361. {
  362.     ULONG Waiting;
  363.  
  364.     Waiting = 0;
  365.  
  366.     if(ReadQueued)
  367.     {
  368.         if(!CheckSerialRead())
  369.             return(0);
  370.         else
  371.             Waiting += ReadRequest->IOSer.io_Actual;
  372.     }
  373.  
  374.     if(WriteRequest)
  375.     {
  376.         if(WriteQueued)
  377.             StopSerialWrite();
  378.  
  379.         WriteRequest->IOSer.io_Command = SDCMD_QUERY;
  380.  
  381.         DoIO((struct IORequest *)WriteRequest);
  382.  
  383.         Waiting += WriteRequest->IOSer.io_Actual;
  384.     }
  385.  
  386.     return(Waiting);
  387. }
  388.  
  389.     /* GetSerialStatus():
  390.      *
  391.      *    Query the current serial port status.
  392.      */
  393.  
  394. LONG
  395. GetSerialStatus()
  396. {
  397.     if(WriteRequest)
  398.     {
  399.         if(WriteQueued)
  400.             StopSerialWrite();
  401.  
  402.         WriteRequest->IOSer.io_Command = SDCMD_QUERY;
  403.  
  404.         DoIO((struct IORequest *)WriteRequest);
  405.  
  406.         return(WriteRequest->io_Status);
  407.     }
  408.     else
  409.         return(CIAF_COMCD | CIAF_COMDSR);
  410. }
  411.  
  412.     /* GetSerialInfo(ULONG *Waiting,UWORD *Status):
  413.      *
  414.      *    Query both the number of bytes waiting to be read and
  415.      *    the current serial status.
  416.      */
  417.  
  418. VOID
  419. GetSerialInfo(ULONG *Waiting,UWORD *Status)
  420. {
  421.     if(WriteRequest)
  422.     {
  423.         if(WriteQueued)
  424.             StopSerialWrite();
  425.  
  426.         WriteRequest->IOSer.io_Command = SDCMD_QUERY;
  427.  
  428.         DoIO((struct IORequest *)WriteRequest);
  429.  
  430.         *Waiting    = WriteRequest->IOSer.io_Actual;
  431.         *Status        = WriteRequest->io_Status;
  432.     }
  433.     else
  434.     {
  435.         *Waiting    = 0;
  436.         *Status        = CIAF_COMCD | CIAF_COMDSR;
  437.     }
  438. }
  439.  
  440.     /* SetSerialAttributes():
  441.      *
  442.      *    Set the serial driver attributes.
  443.      */
  444.  
  445. STATIC VOID
  446. SetSerialAttributes(struct IOExtSer *Request,struct TagItem *Tags)
  447. {
  448.     struct TagItem *Tag;
  449.  
  450.     while(Tag = NextTagItem(&Tags))
  451.     {
  452.         switch(Tag->ti_Tag)
  453.         {
  454.             case SERA_Baud:
  455.  
  456.                 Request->io_Baud = Tag->ti_Data;
  457.                 break;
  458.  
  459.             case SERA_BreakTime:
  460.  
  461.                 Request->io_BrkTime = Tag->ti_Data;
  462.                 break;
  463.  
  464.             case SERA_BitsPerChar:
  465.  
  466.                 Request->io_ReadLen    = Tag->ti_Data;
  467.                 Request->io_WriteLen    = Tag->ti_Data;
  468.                 break;
  469.  
  470.             case SERA_StopBits:
  471.  
  472.                 Request->io_StopBits = Tag->ti_Data;
  473.                 break;
  474.  
  475.             case SERA_BufferSize:
  476.  
  477.                 Request->io_RBufLen = Tag->ti_Data;
  478.                 break;
  479.  
  480.             case SERA_Parity:
  481.  
  482.                 Request->io_ExtFlags &= ~(SEXTF_MSPON | SEXTF_MARK);
  483.                 Request->io_SerFlags &= ~(SERF_PARTY_ON | SERF_PARTY_ODD);
  484.  
  485.                 switch(Tag->ti_Data)
  486.                 {
  487.                     case PARITY_EVEN:
  488.  
  489.                         Request->io_SerFlags |= SERF_PARTY_ON;
  490.                         break;
  491.  
  492.                     case PARITY_ODD:
  493.  
  494.                         Request->io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
  495.                         break;
  496.  
  497.                     case PARITY_MARK:
  498.  
  499.                         Request->io_SerFlags |= SERF_PARTY_ON;
  500.                         Request->io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
  501.                         break;
  502.  
  503.                     case PARITY_SPACE:
  504.  
  505.                         Request->io_SerFlags |= SERF_PARTY_ON;
  506.                         Request->io_ExtFlags |= SEXTF_MSPON;
  507.                         break;
  508.                 }
  509.  
  510.                 break;
  511.  
  512.             case SERA_Handshaking:
  513.  
  514.                 if(Tag->ti_Data == HANDSHAKING_NONE)
  515.                     Request->io_SerFlags &= ~SERF_7WIRE;
  516.                 else
  517.                     Request->io_SerFlags |=  SERF_7WIRE;
  518.  
  519.                 break;
  520.  
  521.             case SERA_HighSpeed:
  522.  
  523.                 if(Tag->ti_Data)
  524.                     Request->io_SerFlags |=  SERF_RAD_BOOGIE;
  525.                 else
  526.                     Request->io_SerFlags &= ~SERF_RAD_BOOGIE;
  527.  
  528.                 break;
  529.  
  530.             case SERA_Shared:
  531.  
  532.                 if(Tag->ti_Data)
  533.                     Request->io_SerFlags |=  SERF_SHARED;
  534.                 else
  535.                     Request->io_SerFlags &= ~SERF_SHARED;
  536.  
  537.                 break;
  538.         }
  539.     }
  540.  
  541.     Request->io_SerFlags |= SERF_XDISABLED;
  542. }
  543.  
  544.     /* GetSerialAttributes():
  545.      *
  546.      *    Get the serial driver attributes.
  547.      */
  548.  
  549. STATIC ULONG
  550. GetSerialAttributes(struct IOExtSer *Request,struct TagItem *Tags)
  551. {
  552.     struct TagItem    *Tag;
  553.     ULONG            *Data;
  554.     ULONG             Result;
  555.  
  556.     Result = NULL;
  557.  
  558.     while(Tag = NextTagItem(&Tags))
  559.     {
  560.         if(!(Data = (ULONG *)Tag->ti_Data))
  561.             Data = &Result;
  562.  
  563.         switch(Tag->ti_Tag)
  564.         {
  565.             case SERA_Baud:
  566.  
  567.                 *Data = Request->io_Baud;
  568.                 break;
  569.  
  570.             case SERA_BreakTime:
  571.  
  572.                 *Data = Request->io_BrkTime;
  573.                 break;
  574.  
  575.             case SERA_BitsPerChar:
  576.  
  577.                 *Data = Request->io_ReadLen;
  578.                 break;
  579.  
  580.             case SERA_StopBits:
  581.  
  582.                 *Data = Request->io_StopBits;
  583.                 break;
  584.  
  585.             case SERA_BufferSize:
  586.  
  587.                 *Data = Request->io_RBufLen;
  588.                 break;
  589.  
  590.             case SERA_Parity:
  591.  
  592.                 Request->io_ExtFlags &= ~(SEXTF_MSPON | SEXTF_MARK);
  593.                 Request->io_SerFlags &= ~(SERF_PARTY_ON | SERF_PARTY_ODD);
  594.  
  595.                 switch(Tag->ti_Data)
  596.                 {
  597.                     case PARITY_EVEN:
  598.  
  599.                         Request->io_SerFlags |= SERF_PARTY_ON;
  600.                         break;
  601.  
  602.                     case PARITY_ODD:
  603.  
  604.                         Request->io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
  605.                         break;
  606.  
  607.                     case PARITY_MARK:
  608.  
  609.                         Request->io_SerFlags |= SERF_PARTY_ON;
  610.                         Request->io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
  611.                         break;
  612.  
  613.                     case PARITY_SPACE:
  614.  
  615.                         Request->io_SerFlags |= SERF_PARTY_ON;
  616.                         Request->io_ExtFlags |= SEXTF_MSPON;
  617.                         break;
  618.                 }
  619.  
  620.                 switch(Request->io_ExtFlags & (SEXTF_MSPON | SEXTF_MARK))
  621.                 {
  622.                     case SEXTF_MSPON | SEXTF_MARK:
  623.  
  624.                         *Data = PARITY_MARK;
  625.                         break;
  626.  
  627.                     case SEXTF_MSPON:
  628.  
  629.                         *Data = PARITY_SPACE;
  630.                         break;
  631.  
  632.                     default:
  633.  
  634.                         switch(Request->io_SerFlags & (SERF_PARTY_ON | SERF_PARTY_ODD))
  635.                         {
  636.                             case SERF_PARTY_ON | SERF_PARTY_ODD:
  637.  
  638.                                 *Data = PARITY_ODD;
  639.                                 break;
  640.  
  641.                             case SERF_PARTY_ON:
  642.  
  643.                                 *Data = PARITY_EVEN;
  644.                                 break;
  645.  
  646.                             default:
  647.  
  648.                                 *Data = PARITY_NONE;
  649.                                 break;
  650.                         }
  651.  
  652.                         break;
  653.                 }
  654.  
  655.                 break;
  656.  
  657.             case SERA_Handshaking:
  658.  
  659.                 if(Request->io_SerFlags & SERF_7WIRE)
  660.                     *Data = TRUE;
  661.                 else
  662.                     *Data = FALSE;
  663.  
  664.                 break;
  665.  
  666.             case SERA_HighSpeed:
  667.  
  668.                 if(Request->io_SerFlags & SERF_RAD_BOOGIE)
  669.                     *Data = TRUE;
  670.                 else
  671.                     *Data = FALSE;
  672.  
  673.                 break;
  674.  
  675.             case SERA_Shared:
  676.  
  677.                 if(Request->io_SerFlags & SERF_SHARED)
  678.                     *Data = TRUE;
  679.                 else
  680.                     *Data = FALSE;
  681.  
  682.                 break;
  683.         }
  684.     }
  685.  
  686.     return(Result);
  687. }
  688.  
  689.     /* SetBothSerialAttributes():
  690.      *
  691.      *    Set the serial read driver parameters.
  692.      */
  693.  
  694. BYTE
  695. SetBothSerialAttributes(Tag FirstTag,...)
  696. {
  697.     if(ReadRequest && WriteRequest)
  698.     {
  699.         BYTE Result;
  700.  
  701.         if(ReadQueued)
  702.             StopSerialRead();
  703.  
  704.         if(WriteQueued)
  705.             StopSerialWrite();
  706.  
  707.         SetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag);
  708.  
  709.         if(ReadRequest->IOSer.io_Device)
  710.         {
  711.             ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS;
  712.  
  713.             Result = DoIO((struct IORequest *)ReadRequest);
  714.         }
  715.         else
  716.             Result = 0;
  717.  
  718.         if(!Result)
  719.         {
  720.             struct MsgPort *OldWritePort = WriteRequest->IOSer.io_Message.mn_ReplyPort;
  721.  
  722.             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  723.  
  724.             WriteRequest->IOSer.io_Message.mn_ReplyPort = OldWritePort;
  725.         }
  726.  
  727.         return(Result);
  728.     }
  729.     else
  730.         return(IOERR_SELFTEST);
  731. }
  732.  
  733.     /* SetSerialReadAttributes():
  734.      *
  735.      *    Set the serial read driver parameters.
  736.      */
  737.  
  738. BYTE
  739. SetSerialReadAttributes(Tag FirstTag,...)
  740. {
  741.     if(ReadRequest)
  742.     {
  743.         if(ReadQueued)
  744.             StopSerialRead();
  745.  
  746.         SetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag);
  747.  
  748.         if(ReadRequest->IOSer.io_Device)
  749.         {
  750.             ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS;
  751.  
  752.             return(DoIO((struct IORequest *)ReadRequest));
  753.         }
  754.         else
  755.             return(0);
  756.     }
  757.     else
  758.         return(IOERR_SELFTEST);
  759. }
  760.  
  761.     /* GetSerialWriteAttributes():
  762.      *
  763.      *    Get the serial write driver parameters.
  764.      */
  765.  
  766. ULONG
  767. GetSerialWriteAttributes(Tag FirstTag,...)
  768. {
  769.     if(WriteRequest)
  770.         return(GetSerialAttributes(WriteRequest,(struct TagItem *)&FirstTag));
  771.     else
  772.         return(NULL);
  773. }
  774.  
  775.     /* DropDTR(STRPTR Device,LONG Unit):
  776.      *
  777.      *    Drops the DTR signal on the currently open device.
  778.      */
  779.  
  780. BOOL
  781. DropDTR(STRPTR Device,LONG Unit)
  782. {
  783.     UBYTE *WasQueueReadBuffer;
  784.     LONG WasQueueReadSize;
  785.     BOOL WasReading;
  786.  
  787.     WasReading            = ReadQueued;
  788.     WasQueueReadBuffer    = QueueReadBuffer;
  789.     WasQueueReadSize    = QueueReadSize;
  790.  
  791.     StopSerialRead();
  792.  
  793.         /* Do we have a valid environment? */
  794.  
  795.     if(WriteRequest)
  796.     {
  797.             /* We'll start with the special line signal control commands */
  798.             /* as supported by the ASDG dual serial board. */
  799.  
  800.         WriteRequest->IOSer.io_Command    = SIOCMD_SETCTRLLINES;
  801.         WriteRequest->IOSer.io_Offset    = SIOB_DTRF;
  802.         WriteRequest->IOSer.io_Length    = 0;
  803.  
  804.         if(!DoIO((struct IORequest *)WriteRequest))
  805.         {
  806.                 /* Ok, so that did work. Now we wait a little... */
  807.  
  808.             DelayTime(1,0);
  809.  
  810.                 /* And we raise the DTR signal again */
  811.  
  812.             WriteRequest->IOSer.io_Command    = SIOCMD_SETCTRLLINES;
  813.             WriteRequest->IOSer.io_Offset    = SIOB_DTRF;
  814.             WriteRequest->IOSer.io_Length    = SIOB_DTRF;
  815.  
  816.             DoIO((struct IORequest *)WriteRequest);
  817.         }
  818.         else
  819.         {
  820.                 /* So that didn't work; we'll have to open and close */
  821.                 /* the device in order to make the driver drop the */
  822.                 /* DTR signal. */
  823.  
  824.             CloseDevice((struct IORequest *)ReadRequest);
  825.  
  826.                 /* Wait a little... */
  827.  
  828.             DelayTime(1,0);
  829.  
  830.                 /* And reopen the driver again; note that since we closed */
  831.                 /* it nothing should have modified the default settings */
  832.  
  833.             if(OpenSerialDevice(Device,Unit))
  834.             {
  835.                     /* Who knows what happened, the device didn't open */
  836.                     /* and we will have to clean up now */
  837.  
  838.                 ReadRequest->IOSer.io_Device = WriteRequest->IOSer.io_Device = NULL;
  839.  
  840.                 return(FALSE);
  841.             }
  842.         }
  843.     }
  844.  
  845.     if(WasReading)
  846.         StartSerialRead(WasQueueReadBuffer,WasQueueReadSize);
  847.  
  848.     return(TRUE);
  849. }
  850.  
  851.     /* OpenSerialDevice(STRPTR Device,LONG Unit):
  852.      *
  853.      *    Open the serial device driver and update the write
  854.      *    request as well.
  855.      */
  856.  
  857. BYTE
  858. OpenSerialDevice(STRPTR Device,LONG Unit)
  859. {
  860.     BYTE Result;
  861.  
  862.     Result = OpenDevice(Device,Unit,(struct IORequest *)ReadRequest,0);
  863.  
  864.     if(Result == 0)
  865.     {
  866.             /* Was the write request initialized? */
  867.  
  868.         if(WriteRequest->IOSer.io_Device)
  869.         {
  870.             CopyMem(&WriteRequest->io_CtlChar,&ReadRequest->io_CtlChar,ReadRequest->IOSer.io_Message.mn_Length - offsetof(struct IOExtSer,io_CtlChar));
  871.  
  872.             ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS;
  873.             DoIO((struct IORequest *)ReadRequest);
  874.         }
  875.  
  876.             /* Update the write request */
  877.  
  878.         CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  879.  
  880.         WriteRequest->IOSer.io_Message.mn_ReplyPort = WritePort;
  881.     }
  882.  
  883.     return(Result);
  884. }
  885.